const fs = require('fs');
const path = require('path');
const { SyncHook } = require("tapable");
const Compilation = require("./Compilation.js");

module.exports = class Compiler {
    constructor(webpackOptions) {
        this.webpackOptions = webpackOptions;
        this.hooks = {
            run: new SyncHook(['compiler']),
            done: new SyncHook(['stats']),
            emit: new SyncHook(['compilation'])
        };
    }
    run(callback) {
        this.hooks.run.call(this);
        this.compile((stats) => {
            // 13.拿到输出资源列表assets之后，开始写入文件系统
            this.hooks.emit.call(this.compilation);
            let outputPath = this.webpackOptions.output.path;
            if (!fs.existsSync(outputPath)) fs.mkdir(outputPath, err => err);
            for (let filename in stats.assets) {
                let source = stats.assets[filename].source();
                filename = path.join(outputPath, filename);
                fs.writeFileSync(filename, source);
            }
            this.hooks.done.call(stats);
            callback(null, {
                ...stats,
                hasErrors() {
                    return false
                }
            });
        });
    }

    compile(callback) {
        // 4.创建compilation对象，并调用build方法开始编译
        this.compilation = new Compilation(this.webpackOptions);
        this.compilation.build(callback);
    }
}